package pl.edu.pw.perg.compinfodb.dbimport;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.FileSystemXmlApplicationContext;

import pl.edu.pw.perg.compinfodb.manager.IConnectorManager;
import pl.edu.pw.perg.compinfodb.manager.IConnectorNameManager;
import pl.edu.pw.perg.compinfodb.manager.IElementTypeManager;
import pl.edu.pw.perg.compinfodb.manager.IFieldManager;
import pl.edu.pw.perg.compinfodb.manager.IHistoryManager;
import pl.edu.pw.perg.compinfodb.manager.IPhysicalElementManager;
import pl.edu.pw.perg.compinfodb.manager.IVirtualElementManager;
import pl.edu.pw.perg.compinfodb.xls.from.InvalidMetadataFormatException;
import pl.edu.pw.perg.compinfodb.xls.from.XLSMetadataReader;

public class DBImporter extends XLSMetadataReader {

	private IFieldManager fieldManager;
	private IElementTypeManager typeManager;
	private IVirtualElementManager virtualElementManager;
	private IPhysicalElementManager physicalElementManager;
	private IConnectorManager connectorManager;
	private IHistoryManager historyManager;
	private IConnectorNameManager connectorNameManager;
	private static Logger logger = LoggerFactory.getLogger(DBImporter.class);

	public IHistoryManager getHistoryManager() {
		return historyManager;
	}

	public void setHistoryManager(IHistoryManager historyManager) {
		this.historyManager = historyManager;
	}

	public DBImporter() {
		String dbCtxPath = "classpath:pl/edu/pw/perg/compinfodb/dbimport/ctx/dbimport-context.xml";
		FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext(
				dbCtxPath);
		fieldManager = (IFieldManager) ctx.getBean("fieldManager");
		typeManager = (IElementTypeManager) ctx.getBean("typeManager");
		virtualElementManager = (IVirtualElementManager) ctx
				.getBean("virtualElementManager");
		physicalElementManager = (IPhysicalElementManager) ctx
				.getBean("physicalElementManager");
		connectorManager = (IConnectorManager) ctx.getBean("connectorManager");
		historyManager = (IHistoryManager) ctx.getBean("historyManager");
		connectorNameManager = (IConnectorNameManager) ctx.getBean("connectorNameManager");
	}

	public static void main(String[] args) {
		try {
			DBImporter xls = new DBImporter();
			logger.info("Importing XLS spreadsheets into database, please wait...");
			logger.info("Removing old data from database:");
			xls.removeDatabase();
			logger.info("Removed.");
			logger.info("Importing new data:");
			xls.createDatabase();
			logger.info("All spreadsheets imported to database.");

		} catch (ArrayIndexOutOfBoundsException e) {
			logger.error("Column index out of bounds: " + e.getMessage()
					+ ". Check properties file!\n", e);

			System.exit(1);
		} catch (Exception e) {
			logger.error("Exception occured. Please report.", e);
			System.exit(1);
		}

	}

	private void createDatabase() {
		
		logger.info("* Fields");
		fieldManager.saveAll(getFields());
		logger.info("* Types");
		typeManager.saveAll(getTypes());
		logger.info("* Structure");
		virtualElementManager.saveAll(getElementsStructure());
		logger.info("* Connector names");
		connectorNameManager.saveAll(getConnectorNames());
		logger.info("* Connections");
		connectorManager.saveAll(getConnections());
		logger.info("* Modules");
		physicalElementManager.saveAll(getPhysicalElements());
		logger.info("* History");
		historyManager.saveAll(getHistory());

	}

	private void removeDatabase() {

		logger.info("* History");
		historyManager.deleteAll();
		logger.info("* Modules");
		physicalElementManager.deleteAll();
		logger.info("* Connections");
		connectorManager.deleteAll();
		logger.info("* Structure");
		virtualElementManager.deleteAll();
		logger.info("* Connector names");
		connectorNameManager.deleteAll();
		logger.info("* Types");
		typeManager.deleteAll();
		logger.info("* Fields");
		fieldManager.deleteAll();

	}

	@Override
	protected void handleFormatError(InvalidMetadataFormatException e) {
		removeDatabase();
		logger.error("Database not created.", e);
		System.exit(1);
	}

	public void setFieldManager(IFieldManager fieldManager) {
		this.fieldManager = fieldManager;
	}

	public void setTypeManager(IElementTypeManager typeManager) {
		this.typeManager = typeManager;
	}

	public void setVirtualElementManager(
			IVirtualElementManager virtualElementManager) {
		this.virtualElementManager = virtualElementManager;
	}

	public void setPhysicalElementManager(
			IPhysicalElementManager physicalElementManager) {
		this.physicalElementManager = physicalElementManager;
	}

	public void setConnectorManager(IConnectorManager connectorManager) {
		this.connectorManager = connectorManager;
	}

	public void setConnectorNameManager(IConnectorNameManager connectorNameManager) {
		this.connectorNameManager = connectorNameManager;
	}
}
